<?php
################################################
#
# Создание миниатюр изображений
#
################################################
# Форматы: JPG, PNG, GIF
################################################
# Требования: PHP 4.0.6 and GD 2.0.1 или выше
################################################

// Параметры:
// src - путь к оригиналу изображения, которое необходимо уменьшить
// dest - путь к миниатюре, где она должна быть сохранена (если сохранение необходимо)
// x - максимальная ширина
// y - максимальная высота
// q - качество изображения миниатюры от 1 до 100 (наилучшее).
// t - формат создаваемого файла миниатюры. "-1" - то же что и оригинал, 1 = GIF, 2 = JPG, 3 = PNG
// f - сохранить в файл (1) или отобразить в браузере (0).

// Примечание:
// 1. Значение параметра качества изображения (q) для форматов:
//    GIF не имеет смысла, т.к параметр не поддерживается. 
//    JPEG используется значение в диапазоне от 1 до 100 (1 - наихудшее, 100 - наилучшее). 
//    PNG используется шкала качества от 0 до 9 (0 - наилучшее, 9 - наихудшее).
//   
//    Независимо от формата изображения необходимо использовать 
//    шкалу качества JPEG (от 1 до 100). Для формата GIF он будет проигнорирован, а
//    для формата PNG значение этого параметра будет автоматически пересчитано.

// Примеры использования:
// 1. Сохранение на сервер:
//    http://www.site.ru/thumb.php?dest=thumb.jpg&x=100&y=50&src=test.jpg
// 2. Отображение:
//    http://www.site.ru/thumb.php?x=50&y=50&f=0&src=test.jpg


///////////////////////////////////////////////////
/////////////// НАСТРОЙКИ ПО УМОЛЧАНИЮ (Если параметры не переданы)
///////////////////////////////////////////////////

// Сохранить миниатюру в файл (true), вывести в браузер (false)
$save_to_file = true;//f 

// Качество изображения миниатюры
$image_quality = 100;//q

// Формат файла миниатюры 1 = GIF, 2 = JPG, 3 = PNG, -1 = такой же как и у оригинала 
$image_type = -1;

// Максимальные размеры
$max_width = 150;//x (ширина)
$max_height = 100;//y (высота)

// Обрезка изображений перед масштабированием
$cut_width = 0;//x (ширина)
$cut_height = 0;//y (высота)

// Время жизни кэша картинки
$offset = 604800; //кэширование на неделю

$to_name = '';


///////////////////////////////////////////////////
/////////////// ПОЛУЧАЕМ ДАННЫЕ
///////////////////////////////////////////////////

// Сохранять ли миниатюру в файл
if (isset($_REQUEST['f'])) $save_to_file = intval($_REQUEST['f']) == 1;

// Адрес исходного изображения 
if (isset($_REQUEST['src'])) $from_name = urldecode($_REQUEST['src']);
else die("Необходимо указать адрес оригинального изображения.");

// Адрес сохранения миниатюры
if (isset($_REQUEST['dest'])) $to_name = urldecode($_REQUEST['dest']);
else if ($save_to_file) die("Необходимо указать название файла миниатюры.");

// Качество миниатюры
if (isset($_REQUEST['q'])) $image_quality = intval($_REQUEST['q']);

// Формат файла, создаваемой миниатюры
if (isset($_REQUEST['t'])) $image_type = intval($_REQUEST['t']);

// Максимальная ширина миниатюры
if (isset($_REQUEST['x'])) $max_width = intval($_REQUEST['x']);

// Максимальная высота миниатюры
if (isset($_REQUEST['y'])) $max_height = intval($_REQUEST['y']);

// Выделение всей необходимой памяти для изображений
ini_set('memory_limit', '-1');


///////////////////////////////////////////////////
/////////////// ФУНКЦИИ ОБРАБОТКИ
///////////////////////////////////////////////////

function SaveImage($type, $im, $filename, $quality, $to_file = true, $offset) {

  $res = null;

  // Если функция imagegif не включена в сборку библиотеки GD2 генерируем PNG
  if(($type == 1) && !function_exists('imagegif')) $type = 3;

  $result = null;
  switch ($type) {
    case 1:
      if ($to_file) {
        $result = imagegif($im,$filename);
      }
      else {
        header("Content-type: image/gif");
		header("Expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT");
		header("Cache-Control: max-age=expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT, must-revalidate"); 
        $result = imagegif($im);
      }
      break;
    case 2:
      if ($to_file) {
        $result = imagejpeg($im,$filename,$quality);
      }
      else {
        header("Content-type: image/jpeg");
		header("Expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT");
		header("Cache-Control: max-age=expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT, must-revalidate"); 
        $result = imagejpeg($im,'',$quality);
      }
      break;
    case 3:
	  //if (PHP_VERSION >= '5.1.2') {
          //Пересчитываем значение параметра качества для PNG 
      //    $quality = 9 - min( round($quality / 10), 9 );
	  //}
      if ($to_file) {
        $result = imagepng($im,$filename);
      }
      else {
        header("Content-type: image/png");
		header("Expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT");
		header("Cache-Control: max-age=expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT, must-revalidate");        
        $result = imagepng($im,'',$quality);
      }
      break;
  }

  return $res;

}//SaveImage


function ImageCreateFromType($type, $filename) {

 $source_image = null;
 switch ($type) {
   case 1:
     $source_image = imagecreatefromgif($filename);
     break;
   case 2:
     $source_image = imagecreatefromjpeg($filename);
     break;
   case 3:
     $source_image = imagecreatefrompng($filename);
     break;
  }
  return $source_image;
  
}//ImageCreateFromType


function GenerateThumbFile($from_name, $to_name, $max_width, $max_height, $cut_width, $cut_height, $offset) {
  global $save_to_file, $image_type, $image_quality;

  // get source image size (width/height/type)
  // orig_img_type 1 = GIF, 2 = JPG, 3 = PNG
  list($original_width, $original_height, $original_img_type, $img_sizes) = getimagesize($from_name);
  
  // Обрезаем изображение, если значения соответствующих параметров не равно 0 
  if ($cut_width > 0) $original_width = min($cut_width, $original_width);
  if ($cut_height > 0) $original_height = min($cut_height, $original_height);

  // Сохранять миниатюру в формате оригинала или в другом?
  $image_type = ($image_type != -1 ? $image_type : $original_img_type);

  // Проверяем исходный файл изображения на соответствие поддерживаемым форматам
  if ($original_img_type < 1 or $original_img_type > 3) die("Этот тип изображения не поддерживается");

  // Если размер исходного файла больше указанного максимального размера эскиза...
  if ($original_width > $max_width or $original_height > $max_height) {

    // ...уменьшаем
    $percentage_x = $original_width / $max_width;
    $percentage_y = $original_height / $max_height;
	
    if ($percentage_y > $percentage_x) 
	    $max_width = $original_width / $percentage_y;    
    else                 
	    $max_height = $original_height / $percentage_x;
  }
  else {
    // ...сохраняем оригинальный размер
    if ($save_to_file) @copy($from_name, $to_name);
   
    else {
      switch ($image_type) {
        case 1:
            header("Content-type: image/gif");
		    header("Expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT");
		    header("Cache-Control: max-age=expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT, must-revalidate"); 
            include($from_name);
          break;
        case 2:
            header("Content-type: image/jpeg");
		    header("Expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT");
		    header("Cache-Control: max-age=expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT, must-revalidate"); 
            include($from_name);
          break;
        case 3:
            header("Content-type: image/png");
		    header("Expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT");
		    header("Cache-Control: max-age=expires: ". gmdate ("D, d M Y H:i:s", time() + $offset) ." GMT, must-revalidate"); 
            include($from_name);
          break;
      }
    }
    return;
  }

  // 1 = GIF, 2 = JPG, 3 = PNG
  if ($image_type == 1) $new_image = imagecreate($max_width, $max_height); //для GIF  
  else $new_image = imagecreatetruecolor($max_width,$max_height);// JPG и PNG  
  
  // Пересчитываем значение параметра качества для PNG 
  if ($image_type == 3) {
      $image_quality = round(($image_quality / 100) * 10);
      if ($image_quality < 1)
          $image_quality = 1;
      elseif ($image_quality > 10)
              $image_quality = 10;
      $image_quality = 10 - $image_quality;
  }

  // Заливаем фон изображения белым (255,255,255)
  $white = imagecolorallocate($new_image, 255, 255, 255);
  imagefilledrectangle( $new_image, 0, 0, $max_width, $max_height, $white);
  
  // Создаем новое изображение из исходного
  $source_image = ImageCreateFromType($original_img_type, $from_name); 
  
  // Копируем палитру цветов
  imagepalettecopy($new_image,$source_image);

  // Копируем прямоугольную часть одного изображения в другое, 
  // плавно интерполируя пикселные значения таким образом, 
  // что уменьшение размера изображения сохранит его чёткость и яркость
  imagecopyresampled (
    $new_image, $source_image,         // $dst_image, $src_image,
    0, 0, 0, 0,                        // $dst_x, $dst_y, $src_x, $src_y,
    $max_width, $max_height,           // $dst_w, $dst_h,      
    $original_width, $original_height  // $src_w, $src_h
  );
  
  // Сохранение миниатюры в файл
  SaveImage($image_type, $new_image, $to_name, $image_quality, $save_to_file, $offset);
  
}//GenerateThumbFile

// Генерирование миниатюры
GenerateThumbFile($from_name, $to_name, $max_width, $max_height, $cut_width, $cut_height, $offset);

?>